package com.spukmk3me.impl.libgdx;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.spukmk3me.math.Matrix4f;
import com.spukmk3me.math.Rectangle;
import com.spukmk3me.math.Rectanglef;
import com.spukmk3me.video.Font;
import com.spukmk3me.video.Polygon;
import com.spukmk3me.video.Text;
import com.spukmk3me.video.TextSetting;

class LibgdxRenderBatch
{
    LibgdxRenderBatch( SpriteBatch batch )
    {
        this.batch = batch;
        m_mvMatrix = new Matrix4();
        m_tempVertex = new Vector3();
        m_buffer = new float[ 20 ];
    }
    
    void setModelViewMatrix( Matrix4f m )
    {
        m_mvMatrix.set( m.getRawData() );
    }
    
    void drawImg( LibgdxImage texture, float w, float h,
        float u1, float v1, float u2, float v2, float color )
    {
        m_tempVertex.set( 0f, 0f, 0f );
        m_tempVertex.mul( m_mvMatrix );
        m_buffer[ 0 ]   = m_tempVertex.x;
        m_buffer[ 1 ]   = m_tempVertex.y;
        m_buffer[ 2 ]   = color;
        m_buffer[ 3 ]   = u1;
        m_buffer[ 4 ]   = v1;
        
        m_tempVertex.set( w, 0f, 0f );
        m_tempVertex.mul( m_mvMatrix );
        m_buffer[ 5 ]   = m_tempVertex.x;
        m_buffer[ 6 ]   = m_tempVertex.y;
        m_buffer[ 7 ]   = color;
        m_buffer[ 8 ]   = u2;
        m_buffer[ 9 ]   = v1;
        
        m_tempVertex.set( w, h, 0f );
        m_tempVertex.mul( m_mvMatrix );
        m_buffer[ 10 ]  = m_tempVertex.x;
        m_buffer[ 11 ]  = m_tempVertex.y;
        m_buffer[ 12 ]  = color;
        m_buffer[ 13 ]  = u2;
        m_buffer[ 14 ]  = v2;
        
        m_tempVertex.set( 0f, h, 0f );
        m_tempVertex.mul( m_mvMatrix );
        m_buffer[ 15 ]  = m_tempVertex.x;
        m_buffer[ 16 ]  = m_tempVertex.y;
        m_buffer[ 17 ]  = color;
        m_buffer[ 18 ]  = u1;
        m_buffer[ 19 ]  = v2;
        
        batch.draw( texture.gdxTexture, m_buffer, 0, 20 );
        //batch.draw( texture.gdxTexture, 40, 40 );
    }
    
    // Not supported yet
    void drawBlankPolygon( Texture texture, Polygon poly, float color )
    {
        
    }
    
    
    void drawText( Text text, float color )
    {
        char[] s = text.getFilteredString();
        
        if ( s == null )
            return;
        
        Text.TextLineInfo[] info = text.getLineInfo();
        
        for ( int i = 0; i != info.length; ++i )
        {
            drawText( s, text.getFont(), info[ i ].x(), info[ i ].y(),
                info[ i ].offset(), info[ i ].length(), text.getFontSetting(), color );
        }
    }
    
    void drawText( char[] s, Font font, int x, int y, int offset, int length, TextSetting setting, float color )
    {
        if ( s == null )
            return;
        
        LibgdxFont  gdxFont = (LibgdxFont)font;
        Texture     gdxTexture = ((LibgdxImage)font.getImage()).gdxTexture;
        
        Rectangle dimension;
        Rectanglef texCoord;
        
        boolean additionalSpace = false; // Small space after each non-space character.
        char    c = 0;
        
        for ( int j = length; j != 0; --j )
        {
            c = s[ offset ];
            dimension = font.getCharacterDimension( c );
            texCoord = gdxFont.getCharTexCoord( c );
            
            // Spaces are invisible.
            if ( c != ' ' )
            {
                m_tempVertex.set( x, y, 0f );
                m_tempVertex.mul( m_mvMatrix );
                
                m_buffer[ 0 ]   = m_tempVertex.x;
                m_buffer[ 1 ]   = m_tempVertex.y;
                m_buffer[ 2 ]   = color;
                m_buffer[ 3 ]   = texCoord.x;
                m_buffer[ 4 ]   = texCoord.y;
                
                m_tempVertex.set( x + dimension.w, y, 0f );
                m_tempVertex.mul( m_mvMatrix );
                
                m_buffer[ 5 ]   = m_tempVertex.x;
                m_buffer[ 6 ]   = m_tempVertex.y;
                m_buffer[ 7 ]   = color;
                m_buffer[ 8 ]   = texCoord.w;
                m_buffer[ 9 ]   = texCoord.y;
                
                m_tempVertex.set( x + dimension.w, y + dimension.h, 0f );
                m_tempVertex.mul( m_mvMatrix );
                    
                m_buffer[ 10 ]  = m_tempVertex.x;
                m_buffer[ 11 ]  = m_tempVertex.y;
                m_buffer[ 12 ]  = color;
                m_buffer[ 13 ]  = texCoord.w;
                m_buffer[ 14 ]  = texCoord.h;
                
                m_tempVertex.set( x, y + dimension.h, 0f );
                m_tempVertex.mul( m_mvMatrix );
                
                m_buffer[ 15 ]  = m_tempVertex.x;
                m_buffer[ 16 ]  = m_tempVertex.y;
                m_buffer[ 17 ]  = color;
                m_buffer[ 18 ]  = texCoord.x;
                m_buffer[ 19 ]  = texCoord.h;
                
                batch.draw( gdxTexture, m_buffer, 0, 20 );
                x += font.getSpaceBetweenChar() + font.getCharacterDimension( c ).w;
                additionalSpace = true;
            }
            else
            {
                if ( additionalSpace )
                    x -= font.getSpaceBetweenChar();

                x += font.getCharacterDimension( ' ' ).w;
                additionalSpace = false;
            }
            
            ++offset;
        }
    }
    
    final SpriteBatch batch;
    
    private Matrix4 m_mvMatrix;
    private Vector3 m_tempVertex;
    private float[] m_buffer;
}
